package com.flyco.banner.widget.LoopViewPager;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * <a>继承ViewPage 实现 事件添加
 * <p/>
 */
public class LoopViewPager extends ViewPager {
	private static final boolean DEFAULT_BOUNDARY_CASHING = false;
	private LoopPagerAdapterWrapper mAdapter;
	private boolean mBoundaryCaching = DEFAULT_BOUNDARY_CASHING;
	private List<OnPageChangeListener> mOnPageChangeListeners;

	/**
	 * helper函数可以实现FragmentPagerAdapter时使用
	 * @param position
	 * @param count
	 * @return (position-1)%count
	 */
	public static int toRealPosition(int position, int count) {
		position = position - 1;
		if (position < 0) {
			position += count;
		} else {
			position = position % count;
		}
		return position;
	}

	/**
	 * If set to true, the boundary views (i.e. first and last) will never be
	 * destroyed This may help to prevent "blinking" of some views
	 * 如果设置为真,则边界的观点(即第一个和最后一个)永远不会被摧毁,这可能有助于防止“闪烁”的一些看法
	 * 
	 * @param flag
	 */
	public void setBoundaryCaching(boolean flag) {
		mBoundaryCaching = flag;
		if (mAdapter != null) {
			mAdapter.setBoundaryCaching(flag);
		}
	}

	@Override
	public void setAdapter(PagerAdapter adapter) {
		mAdapter = new LoopPagerAdapterWrapper(adapter);
		mAdapter.setBoundaryCaching(mBoundaryCaching);
		super.setAdapter(mAdapter);
		setCurrentItem(0, false);
	}

	@Override
	public PagerAdapter getAdapter() {
		return mAdapter != null ? mAdapter.getRealAdapter() : mAdapter;
	}

	@Override
	public int getCurrentItem() {
		return mAdapter != null ? mAdapter.toRealPosition(super
				.getCurrentItem()) : 0;
	}

	public void setCurrentItem(int item, boolean smoothScroll) {
		int realItem = mAdapter.toInnerPosition(item);
		super.setCurrentItem(realItem, smoothScroll);
	}

	@Override
	public void setCurrentItem(int item) {
		if (getCurrentItem() != item) {
			setCurrentItem(item, true);
		}
	}

	@Override
	public void setOnPageChangeListener(OnPageChangeListener listener) {
		addOnPageChangeListener(listener);
	}

	@Override
	public void addOnPageChangeListener(OnPageChangeListener listener) {
		if (mOnPageChangeListeners == null) {
			mOnPageChangeListeners = new ArrayList<OnPageChangeListener>();
		}
		mOnPageChangeListeners.add(listener);
	}

	@Override
	public void removeOnPageChangeListener(OnPageChangeListener listener) {
		if (mOnPageChangeListeners != null) {
			mOnPageChangeListeners.remove(listener);
		}
	}

	@Override
	public void clearOnPageChangeListeners() {
		if (mOnPageChangeListeners != null) {
			mOnPageChangeListeners.clear();
		}
	}

	public LoopViewPager(Context context) {
		super(context);
		init(context);
	}

	public LoopViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	private void init(Context context) {
		if (onPageChangeListener != null) {
			super.removeOnPageChangeListener(onPageChangeListener);
		}
		super.addOnPageChangeListener(onPageChangeListener);
	}

	private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
		private float mPreviousOffset = -1;
		private float mPreviousPosition = -1;

		@Override
		public void onPageSelected(int position) {
			int realPosition = mAdapter.toRealPosition(position);
			if (mPreviousPosition != realPosition) {
				mPreviousPosition = realPosition;
				if (mOnPageChangeListeners != null) {
					for (int i = 0; i < mOnPageChangeListeners.size(); i++) {
						OnPageChangeListener listener = mOnPageChangeListeners
								.get(i);
						if (listener != null) {
							listener.onPageSelected(realPosition);
						}
					}
				}
			}
		}

		@Override
		public void onPageScrolled(int position, float positionOffset,
				int positionOffsetPixels) {
			int realPosition = position;
			if (mAdapter != null) {
				realPosition = mAdapter.toRealPosition(position);

				if (positionOffset == 0
						&& mPreviousOffset == 0
						&& (position == 0 || position == mAdapter.getCount() - 1)) {
					setCurrentItem(realPosition, false);
				}
			}
			mPreviousOffset = positionOffset;
			if (mOnPageChangeListeners != null) {
				for (int i = 0; i < mOnPageChangeListeners.size(); i++) {
					OnPageChangeListener listener = mOnPageChangeListeners
							.get(i);
					if (listener != null) {
						if (realPosition != mAdapter.getRealCount() - 1) {
							listener.onPageScrolled(realPosition,
									positionOffset, positionOffsetPixels);
						} else {
							if (positionOffset > .5) {
								listener.onPageScrolled(0, 0, 0);
							} else {
								listener.onPageScrolled(realPosition, 0, 0);
							}
						}
					}
				}
			}
		}

		@Override
		public void onPageScrollStateChanged(int state) {
			if (mAdapter != null) {
				int position = LoopViewPager.super.getCurrentItem();
				int realPosition = mAdapter.toRealPosition(position);
				if (state == ViewPager.SCROLL_STATE_IDLE
						&& (position == 0 || position == mAdapter.getCount() - 1)) {
					setCurrentItem(realPosition, false);
				}
			}
			if (mOnPageChangeListeners != null) {
				for (int i = 0; i < mOnPageChangeListeners.size(); i++) {
					OnPageChangeListener listener = mOnPageChangeListeners
							.get(i);
					if (listener != null) {
						listener.onPageScrollStateChanged(state);
					}
				}
			}
		}
	};

}
